package com.cxs.musicplaywidget.widget.controller;

import com.cxs.musicplaywidget.commonevent.EventManager;
import com.cxs.musicplaywidget.data.EventParam;
import com.cxs.musicplaywidget.data.MDevice;
import com.cxs.musicplaywidget.player.data.MusicInfo;
import com.cxs.musicplaywidget.service.DeviceManager;
import com.cxs.musicplaywidget.service.ServiceManager;
import com.cxs.musicplaywidget.util.LogUtils;
import com.cxs.musicplaywidget.view.WidgetControllerAdapter;
import ohos.aafwk.ability.*;
import ohos.app.Context;
import ohos.app.dispatcher.TaskDispatcher;
import ohos.app.dispatcher.task.TaskPriority;
import ohos.data.DatabaseHelper;
import ohos.data.preferences.Preferences;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import ohos.utils.Parcel;
import ohos.utils.zson.ZSONObject;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

import static com.cxs.musicplaywidget.data.EventParam.EventAction.*;
import static com.cxs.musicplaywidget.data.EventParam.EventAction;
import static com.cxs.musicplaywidget.data.EventParam.EventAction.GET_VOLUME;

/**
 * @ClassName WidgetManager
 * @Author cxs
 * @Version 1.0
 * @Description 卡片管理器
 * @Date 2022/03/25
 */
public class WidgetManager {
    private static final String tag = WidgetManager.class.getSimpleName();
    private static final int DIMENSION_1X2 = 1;
    private static final int DIMENSION_2X2 = 2;
    private static final int DIMENSION_4X4 = 4;
    private volatile static WidgetManager instance = null;
    private final Context context;
    private DeviceManager deviceManager;
    private ServiceManager serviceManager;
    TaskDispatcher globalTaskDispatcher;

    private WidgetManager(Context context) {
        this.context = context;
    }

    public static WidgetManager getInstance(Context context) {
        if (instance == null) {
            synchronized (WidgetManager.class) {
                if (instance == null) {
                    instance = new WidgetManager(context);
                }
            }
        }
        return instance;
    }

    public void init() {
        globalTaskDispatcher = context.getApplicationContext().getGlobalTaskDispatcher(TaskPriority.LOW);
        globalTaskDispatcher.asyncDispatch(() -> {
            // 订阅公共事件
            EventManager.subscribe(context);
            // 设备管理器
            deviceManager = DeviceManager.getInstance(context);
            // Service管理器
            serviceManager = ServiceManager.getInstance(context);
        });
    }

    public void sendMessageEvent(String action, ZSONObject param) {
        EventManager.subscribe(context);
        deviceManager = DeviceManager.getInstance(context);
        serviceManager = ServiceManager.getInstance(context);
        LogUtils.debug(tag, "onTriggerFormEvent.action = " + action);
        switch (action) {
            case "changeDevice": {
                // 切换设备
                byte index = param.getByte("index");
                serviceManager.connectService(index);
                break;
            }
            case "refreshDevice": {
                // 重新加载设备
                LogUtils.debug(tag, "sendMessageEvent.refreshDevice");
                List<MDevice> deviceList = deviceManager.getDeviceList(true);
                if (!deviceList.isEmpty()) {
                    EventManager.publishEvent(new EventParam(LOAD_DEVICE_LIST));
                    serviceManager.init();
                }
                break;
            }
            case "reloadPlayList": {
                deviceManager.getDevice().proxy().start(RELOAD_PLAY_LIST);
            }
            case "changeMusic": {
                // 切换音乐
                Integer index = param.getInteger("index");
                LogUtils.debug(tag, "sendMessageEvent.changeMusic.deviceManager=" + deviceManager.getDeviceList());
                deviceManager.getDevice().proxy().addEvent(new EventParam(PLAY, index));
                deviceManager.getDevice().proxy().addEvent(new EventParam(GET_PLAY_LIST));
                deviceManager.getDevice().proxy().start();
                sendPlayingEvent();
                break;
            }
            case "play": {
                // 播放
                deviceManager.getDevice().proxy().start(PLAY);
                deviceManager.getDevice().proxy().start(GET_PLAY_LIST);
                sendPlayingEvent();
                break;
            }
            case "myPlay": {
                String myPlay = param.getString("myPlay");
                MusicInfo musicInfo = ZSONObject.stringToClass(ZSONObject.toZSONString(param), MusicInfo.class);
                MusicInfo musicInfo1 = deviceManager.getDevice().proxy().getMusicDataFromRemote(musicInfo);
                if (myPlay.equals("my_play")) {
                    deviceManager.getDevice().proxy().playMusic(musicInfo1);
                } else {
                    deviceManager.getDevice().proxy().pauseMusic(musicInfo1);
                }
                break;
            }
            case "pause": {
                // 暂停
                deviceManager.getDevice().proxy().start(PAUSE);
                removePlayingEvent();
                break;
            }
            case "previous": {
                // 上一首
                deviceManager.getDevice().proxy().start(PREVIOUS);
                deviceManager.getDevice().proxy().start(GET_PLAY_LIST);
                sendPlayingEvent();
                break;
            }
            case "next": {
                // 下一首
                deviceManager.getDevice().proxy().start(NEXT);
                deviceManager.getDevice().proxy().start(GET_PLAY_LIST);
                sendPlayingEvent();
                break;
            }
            case "decrease": {
                // 减小音量
                deviceManager.getDevice().proxy().start(DECREASE);
                deviceManager.getDevice().proxy().start(GET_VOLUME);
                break;
            }
            case "increase": {
                // 增加音量
                deviceManager.getDevice().proxy().start(INCREASE);
                deviceManager.getDevice().proxy().start(GET_VOLUME);
                break;
            }
        }
    }

    private void sendPlayingEvent() {
        removePlayingEvent();
        MusicInfo musicInfo = deviceManager.getDevice().proxy().getMusicInfo();
        byte[] thumbnail = deviceManager.getDevice().proxy().getThumbnail();
        int thumbIndex = deviceManager.getDevice().proxy().thumbIndex;
        new WidgetControllerAdapter(context).updateMusicInfo(musicInfo);
        new WidgetControllerAdapter(context).updateThumbnail(thumbnail, thumbIndex);
        LogUtils.debug(tag, "sendPlayingEvent.thumbnail=" + thumbnail);
        // 封面为null时，param传入默认封面的当前旋转的图片索引, 封面不为null时，param传入0
        eventHandler.sendEvent(InnerEvent.get(ISPLAYING, thumbnail == null ? (long)thumbIndex : (long)0));
    }

    private void removePlayingEvent() {
        if (eventHandler.hasInnerEvent(ISPLAYING)) {
            eventHandler.removeEvent(ISPLAYING);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            removePlayingEvent();
        }
    }

    private static final int ISPLAYING = 0;
    EventHandler eventHandler = new EventHandler(EventRunner.create()) {
        @Override
        protected void processEvent(InnerEvent event) {
            switch (event.eventId) {
                case ISPLAYING: {
                    LogUtils.debug(tag, "event.param=" + event.param);
                    // 更新卡片歌曲封面
                    if (event.param != 0) {
                        deviceManager.getDevice().proxy().thumbIndex = (int)event.param;
                        // param不为0时，封面为null
                        if (event.param >= 35) {
                            event.param = 1;
                        }
                        new WidgetControllerAdapter(context).updateThumbnail(null, (int)event.param);
                        event.param++;
                    }

                    eventHandler.sendEvent(InnerEvent.get(ISPLAYING, event.param), 1000);
                    break;
                }
            }
        }
    };

}
